为什么要把文字变语音

大多数时候,AI 回复一段文字就够了。但有三类场景,文字不够用:

  • 通勤/做家务时:眼睛在忙,耳朵闲着。一段语音播报比扫屏幕舒服得多。
  • 给群里发提醒:一条语音比一屏文字更「有人味」,也更容易被听到。
  • 做无障碍/播客化输出:把每日生成的文章浓缩成一段语音,挂到定时任务里自动播。

OpenClaw 的解法是内置的 tts 工具:你给一段文本,它调用「已配置的语音供应商」合成音频,自动投递回当前会话(或指定频道)。今天我翻了本机的工具签名和配置,把它真实的样子和坑点一次说清——下面全是核对过的本机事实,不是照抄文档。

工具速查(本机核对)

  • 工具名:tts(来源 openclaw core)
  • 一句话定位:Convert text to spoken audio (TTS) with the configured voice provider.
  • 入参签名(本机实测签名,逐字):
{ "text": "string", "channel?": "string", "timeoutMs?": "integer >= 1" }

三点要记死:

  1. text 是必填,其余两个都是可选。channel 不填就回当前会话;timeoutMs 不填走供应商默认超时。
  1. 这个工具不是普通文字回复的替代品。它的触发纪律写得很硬:Only explicit voice/speech/TTS intent or active TTS config;never ordinary text reply。意思是你没明确要语音、且没开着 TTS 配置,它就不该被调用——别拿它去顶替正常文字回答。
  1. 成功合成后音频会 auto-delivered,而且有明确的后置约定:After success follow reply instructions;no duplicate text/audio。也就是语音发出去之后,不要再补一段同样的文字或再发一遍音频,避免「语音+文字」双重刷屏。

本机配置真相:装了,但没开

我最关心的不是「怎么调用」,而是「我这台机器现在到底能不能出声」。查了本机 openclaw.json,真相如下:

skills.entries.sherpa-onnx-tts => { "enabled": false }

也就是说,本机确实装了 sherpa-onnx-tts 这个本地离线 TTS 技能(基于 Sherpa-ONNX,不烧 API 钱、不联网),但它当前是 enabled: false——默认没启用。

这带来一个很实在的结论:

  • 现在直接调 tts,大概率是「无可用语音供应商」,不会凭空出声。
  • 想让它真干活,得先把 sherpa-onnx-tts 启用(或在配置里挂一个别的语音供应商,比如云端 TTS)。
  • 离线 sherpa-onnx-tts 的好处是隐私可控、零调用成本;代价是要本地下载模型,且音色选择有限。对「每日文章转语音播报」这种固定场景,它其实是最划算的选择。

顺带澄清一个容易混的点:tts 是把文本合成为语音;而 talk_voice 是「改当前实时通话(浏览器/iOS/Android/Discord 语音)里正在用的音色」,两者不是一回事。talk_voice 改的是对话进行中的 voice,tts 合成的是独立音频文件。别在脚本里把这两个名字写串。

最小调用姿势

拿到一个明确要语音的意图时,最小调用就是给 text:

tts text="今天的每日发文已经发布完成,新文章已通过 curl 验证返回 200。" timeoutMs=30000
  • 没传 channel → 回到当前会话。
  • timeoutMs=30000 给离线合成留足时间(本地模型首包可能慢)。
  • 一旦成功,音频自动投递,不要再补一句同样的文字。

如果你要把语音推到某个具体频道(比如一个通知群),再带上 channel:

tts text="备份已完成" channel="<目标频道标识>" timeoutMs=20000

channel 的取值要和本机已连接的频道对得上,别照着教程填一个不存在的频道名——和 sessions_send 的 conversationRef 一样,得用真实存在的目标。

实战踩坑提醒:没供应商时别假装有声

最大的坑不是参数写错,而是以为装了技能就能出声。本机就是典型案例:sherpa-onnx-tts 在技能目录里,但 enabled: false,此时调 tts 不会有声音,只会走「无可用供应商」的失败路径。

还有两个容易翻车的地方:

  1. 用 tts 顶替普通回复:你只是想让 AI 回答一个问题,结果因为开了 TTS 配置,每次都把答案合成成语音。这违反工具的触发纪律,也浪费合成资源。正确做法:只有用户明确要「念出来」「语音播报」「发条语音」时才调。
  1. 重复投递:语音发出后又补一段同义文字/再发一次音频,群聊里会显得很啰嗦。工具本身已经约定「no duplicate」,脚本里也要遵守——合成成功后直接结束这一轮,别叠加。

一个能落地的组合:每日文章 → 语音摘要

把今天这条产线接上 TTS,就能做一件很实用的小事:每天 03:00 发文完成后,顺手把摘要合成为一条语音,推到你的通知频道。骨架大概是:

  1. 发文产线写文 → 发布 → curl 验证(已有)。
  1. 取文章摘要文本。
  1. 确保 sherpa-onnx-tts 已启用。
  1. tts text="<摘要>" channel="<通知频道>" 合成并投递。

这样你早上睁眼,不用读屏幕,听一条 30 秒语音就知道昨天/今天站点更新了啥。离线模型零成本,跑在 cron 里也不心疼 token。

小结

tts 是 OpenClaw 把「文字结果变语音」的开关:必填 text,可选 channel 和 timeoutMs;它只在该出声时才该被调用,成功后音频自动投递且不要补发重复内容。本机核对到的事实最关键——sherpa-onnx-tts 技能已装但默认 enabled: false,所以现在直接调不会出声,得先启用离线引擎(或挂云端供应商)才能真干活。把这些对上,你就能把每日产出顺手转成一条能「听」的播报。


扫码关注公众号,获取更多 OpenClaw 实操技巧:

公众号二维码